import re

import cn2an


class PriceMixIn(object):
    @staticmethod
    def process_money(money_string: str) -> float:
        '''
        process_money 3.2.3
        1.过滤所有与金额无关字符
        2.输出万为单位的小数点6位的浮点数
        需要注意的事项：
            0.默认单位为元,即 输入15000 --> 输出1.5000
            1.存在 / ,'%','率' 返回0.0'
            2.第一个数字的所有字符会被删除,除了:([十百千]万元)654.263472
            3.默认单位为元元元元元元元元元元元元元！！！！！！！！！！！！！！！！！
        '''
        _money_str = str(money_string)
        _money_str = _money_str.strip().replace('　', '').replace(' ', '')  # 去除中英文空格
        _money_str = re.sub(r'[\r\t\n]', '', _money_str)
        _money_str = re.sub(r'[()（）]', '', _money_str)
        _money_str = re.sub(r'[:：]', '', _money_str)
        # 第一轮处理
        _money_str = re.sub(r'[．]', '.', _money_str)  # 处理特殊符号
        _money_str = re.sub(r'[,]', '', _money_str)  # 处理逗号
        _money_str = re.sub(r'(^[^十百千]?万元)([\d.]*)$', r'\2\1', _money_str)  # 单位置换到数字后
        _money_str = re.sub(r'^\D+(\d)', r'\1', _money_str)  # 去除第一数字之前的所有字符,
        # 针对此类数据（/年/月/日，/件）
        if any(i in _money_str for i in ['/']):
            _money_str = ''
        _money_str = re.sub(r'(.*)元.*', r'\1', _money_str)  # 去除最后一个元之后的所有字符
        # 将此类数据（2.3万元，5千万）转换成纯数字（23000.0，50000000.0）
        try:
            if re.search(r'(\d+[.\d]*?)(十万|百万|千万|万|十亿|亿)', _money_str):
                _money_str = re.sub(r'(\d+[.\d]*?)(十万|百万|千万|万|十亿|亿)',
                                    lambda x: str(float(x.group(1)) * cn2an.cn2an(f'一{x.group(2)}')),
                                    _money_str)  # 浮点数 * 单位
        except Exception as e:
            print(e)
            print(f'金额异常!{money_string}')
            _money_str = "0"

        # 经过第一轮处理后存在多组数组，重新审查_money_str，拿到相对较大的数组
        try:
            if len(re.findall(r'\d+[.\d]*', _money_str, re.S)) > 1:
                z = re.findall(r'\d+[.\d]*', _money_str, re.S)
                _money_str = sorted(z, key=lambda x: float(x), reverse=True)[0]
        except Exception as e:
            print(e)
            print(f'金额异常!{money_string}')
            _money_str = "0"

        # 第二轮处理
        _money_str = re.sub(r'(.*)元.*', r'\1', _money_str)  # 去除最后一个元之后的所有字符
        _money_str = _money_str.replace('萬', '万')
        _money_str = re.sub(r'[^\d.零壹贰叁肆伍陆柒捌玖拾佰仟一二三四五六七八九十百千万亿%‰率]', '', _money_str)  # 去掉无关字符

        # 处理小数点数量>1 返回0（出于安全考虑）
        count_p = _money_str.count(".")
        if count_p > 1:
            print(f'金额异常!{money_string}')
            _money_str = "0"

        money = 0  # 类型：int/float，用于区分money_string
        if _money_str != '':
            if _money_str.replace('.', '').isdigit():
                money = float(_money_str)
            elif any(i in _money_str for i in ['%', '‰', '率']):
                money = 0
            elif isinstance(_money_str, str):
                try:
                    # 针对此类数据（2.3万元, 200万，5千万）
                    if re.search(r'(^\d+[.\d]*?)(十万|百万|千万|万|十亿|亿)', _money_str):
                        _money_str = re.sub(r'(^\d+[.\d]*?)(十万|百万|千万|万|十亿|亿)',
                                            lambda x: str(float(x.group(1)) * cn2an.cn2an(f'一{x.group(2)}')),
                                            _money_str)  # 浮点数 * 单位
                        money = float(_money_str)

                    # 比较数字金额与文本金额的大小，针对此类数据（小写100,000.00 大写：拾万元）
                    elif re.search(r'(^[\d.]+)(\D+$)', _money_str):
                        an = re.search(r'(^[\d.]+)(\D+$)', _money_str).group(1)
                        cn = re.search(r'(^[\d.]+)(\D+$)', _money_str).group(2)
                        money = float(an) if float(an) > cn2an.cn2an(cn) else cn2an.cn2an(cn)

                    # 不符合这些情况的交给 cn2an('smart')处理, 针对此类数据（2百30万）
                    else:
                        money = cn2an.cn2an(_money_str, 'smart')

                # 报错为0（出于安全考虑）
                except:
                    money = 0

        # 100元一下的数据返回0，针对此类数据（20%, 20元/件）只取到了20、20元
        if money <= 2100.0:
            money = 0
        return round(money / 10000.0, 6)


if __name__ == '__main__':
    M = PriceMixIn()
    print(M.process_money('报价:580000(元)'))
